from django import forms
from django.http import JsonResponse
from django.views.generic import View

from main.decorators import require_username, check_object_id, validate_input
from main.models.subscription import Subscription, SubscriptionFollower
from main.responses import *


class AllSubscriptionList(View):
    get_dict = {
        'order': forms.IntegerField(required=False, min_value=0, max_value=3),
    }
    available_orders = [
        'create_time', '-create_time',
        'name', '-name',
    ]

    @validate_input(get_dict)
    @require_username
    def get(self, request, order=1):
        """
        获取公众号列表

        :param order: 排序方式
            0: 注册时间升序
            1: 注册时间降序（默认值）
            2: 昵称升序
            3: 昵称降序
        :return:
            count: 公众号总数
            list: 公众号列表
                id: 公众号号ID
                name: 公众号名称
                owner_id: 所有者ID
                create_time: 注册时间
        """
        k = self.available_orders[order]

        c = Subscription.enabled.count()
        subscriptions = Subscription.enabled.order_by(k)
        l = [{'id': s.id,
              'name': s.name,
              'owner_id': s.owner.id,
              'create_time': s.create_time} for s in subscriptions]
        return JsonResponse({'count': c, 'list': l})


class SubscriptionList(View):
    get_dict = {
        'order': forms.IntegerField(required=False, min_value=0, max_value=3),
    }
    available_orders = [
        'create_time', '-create_time',
        'name', '-name',
    ]

    @validate_input(get_dict)
    @require_username
    def get(self, request, order=1, is_owner=True):
        """
        获取自己创建的公众号列表
        :param offset: 偏移量
        :param limit: 数量上限
        :param order: 排序方式
            0: 注册时间升序
            1: 注册时间降序（默认值）
            2: 昵称升序
            3: 昵称降序
        :return:
            count: 公众号总数
            list: 公众号列表
                id: 公众号号ID
                name: 公众号名称
                create_time: 注册时间
        """
        k = self.available_orders[order]

        c = Subscription.enabled.filter(owner=request.user).count()
        subscriptions = Subscription.enabled.filter(owner=request.user)\
            .order_by(k)
        
        l = [{'id': s.id,
              'name': s.name,
              'create_time': s.create_time} for s in subscriptions]
        return JsonResponse({'count': c, 'list': l})


class SubscriptionFollowerList(View):
    get_dict = {
        'order': forms.IntegerField(required=False, min_value=0, max_value=3),
    }
    available_orders = (
        'create_time', '-create_time',
        'follower__name', '-follower__name',
    )

    @check_object_id(Subscription.enabled, 'subscription')
    @require_username
    @validate_input(get_dict)
    def get(self, request, subscription, order=1):
        """
        获取公众号的关注者列表

        :param subscription_id: 公众号ID
        :param offset: 偏移量
        :param limit: 数量上限
        :param order: 排序方式
            0: 成为关注者时间升序
            1: 成为关注者时间降序（默认值）
            2: 昵称升序
            3: 昵称降序
        :return:
            count: 关注者总数
            list: 关注者列表
                id: 用户ID
                username: 用户名
                name: 用户昵称
                create_time: 成为关注者时间
        """
        k = self.available_orders[order]

        c = SubscriptionFollower.enabled.filter(subscription=subscription)\
            .count()
        rs = SubscriptionFollower.enabled.filter(subscription=subscription)\
            .order_by(k)

        l = [{'id': r.follower.id,
              'username': r.follower.username,
              'name': r.follower.name,
              'create_time': r.create_time} for r in rs]
        return JsonResponse({'count': c, 'list': l})

    @check_object_id(Subscription.enabled, 'subscription')
    @require_username
    def post(self, request, subscription):
        """
        目标用户关注公众号

        """
        # 若是自己的公众号则不处理
        if subscription.owner == request.user:
            return Http403('can not follow your own subscription')
        # 若对方已关注则不做处理
        if SubscriptionFollower.exist(request.user, subscription):
            return Http404('already been follower')

        subscription.follower_records.create(follower=request.user)
        return Http200()
